using System;
using System.Data;

using System.IO;

namespace hemsidan.Entities
{
	/// <summary>
	/// Summary description for PhotoGallery.
	/// </summary>
	public class PhotoGallery
	{
		public const string ZIP_FILE = "zip";
		public const string JPG_FILE = "jpeg";

		private PhotoGallery()
		{
		}

		public static DataTable GetRecent(int count)
		{
			string sql = "select * from PhotoGalleries order by Created desc LIMIT 0," + count.ToString();
			DataTable table = DataAccess.DB.getInstance().ExecuteDataSet(sql).Tables[0];

			for(int i=count; table.Rows.Count > i; i++)
			{
				table.Rows.RemoveAt(i);
			}
			return table;
		}

		public static DataTable GetAllGalleries()
		{
            string sql = "select * from PhotoGalleries order by Created desc";
			DataSet ds = DataAccess.DB.getInstance().ExecuteDataSet(sql);
			return ds.Tables[0];
		}

		public static DataTable GetGalleryContent(int GalleryId)
		{
			string sql = "select * from Photos where GalleryId=" + GalleryId.ToString();
			DataSet ds = DataAccess.DB.getInstance().ExecuteDataSet(sql);
			return ds.Tables[0];
		}

		private static void UnZip(System.IO.Stream s, string Name)
		{
			string MappedPath = Helpers.Settings.GalleryRoot + Name;
			string VirtualPath = Helpers.Settings.VirtualRoot + Helpers.Settings.GalleryFolder + Name;

			ICSharpCode.SharpZipLib.Zip.ZipInputStream zis = new ICSharpCode.SharpZipLib.Zip.ZipInputStream( s);
			System.IO.Directory.CreateDirectory(MappedPath);

			ICSharpCode.SharpZipLib.Zip.ZipEntry entry;

			entry = zis.GetNextEntry();
			while (entry != null)
			{
				string directoryName = System.IO.Path.GetDirectoryName(entry.Name);
				string fileName      = System.IO.Path.GetFileName(entry.Name);
			
				if (entry.IsDirectory)
					Directory.CreateDirectory(directoryName);
			
				if (fileName != String.Empty) 
				{
					System.IO.FileStream streamWriter = File.Create(MappedPath + "\\" + entry.Name);
				
					int size = 2048;
					byte[] data = new byte[2048];
					while (true) 
					{
						size = zis.Read(data, 0, data.Length);
						if (size > 0) 
						{
							streamWriter.Write(data, 0, size);
						} 
						else 
						{
							break;
						}
					}
				
					streamWriter.Close();
					entry = zis.GetNextEntry();
				}
			}
			s.Close();
		}


		public static void CreateGallery(string Name, string Description, ImageFile image)
		{
			string MappedPath = Helpers.Settings.GalleryRoot + Name;
			string VirtualPath = Helpers.Settings.VirtualRoot + Helpers.Settings.GalleryFolder + Name;

			HandleImageFile(image,Name, MappedPath);
			string sql = "insert into PhotoGalleries (Name, Comment) values ('" + Name + "', '" + Description + "')";
			DataAccess.DB.getInstance().ExecuteNonQuery(sql);
			sql = "select id from PhotoGalleries where Name='" + Name + "' and Comment='" + Description + "'";
			int GalleryId = Convert.ToInt32(DataAccess.DB.getInstance().ExecuteDataSet(sql).Tables[0].Rows[0]["Id"]);
			SyncDirectoryWithDB(MappedPath,VirtualPath, GalleryId.ToString());				
		}

		public static void UpdateGallery(string Id, string Name, string Description)
		{
			string sql = "update PhotoGalleries set Name='" + Name + "', Comment='" + Description + "' where Id=" + Id;
			DataAccess.DB.getInstance().ExecuteNonQuery(sql);
		}

		public static void UpdateGallery(string Id, string Name, string Description, ImageFile image)
		{
			string MappedPath = Helpers.Settings.GalleryRoot + Name;
			string VirtualPath = Helpers.Settings.VirtualRoot + Helpers.Settings.GalleryFolder + Name;

			HandleImageFile(image,Name, MappedPath);
			UpdateGallery(Id, Name, Description);
			SyncDirectoryWithDB(MappedPath, VirtualPath, Id);
		}

		public static void DeleteGallery(string GalleryId)
		{
			string sql = "select Name from PhotoGalleries where id=" + GalleryId;
			DataTable dt = DataAccess.DB.getInstance().ExecuteDataSet(sql).Tables[0];
			string Name = (string)dt.Rows[0][0];
			sql = "delete from Photos where GalleryId=" + GalleryId;
			DataAccess.DB.getInstance().ExecuteNonQuery(sql);
			sql = "delete from PhotoGalleries where Id=" + GalleryId;
			DataAccess.DB.getInstance().ExecuteDataSet(sql);
			System.IO.Directory.Delete(Helpers.Settings.GalleryRoot + Name, true);
	}
		
		private static void SyncDirectoryWithDB(string MappedPath, string VirtualPath, string Id)
		{
			string[] files = System.IO.Directory.GetFiles(MappedPath);
			foreach (string f in files)
			{
				string fShort = f.Substring(f.LastIndexOf("\\"));
				AddPhotoToGallery(VirtualPath + fShort, "", Id);
			}
		}

		private static void AddPhotoToGallery(string Path, string Comment, string GalleryId)
		{
			Path = Path.Replace("\\", "/");
			string sql = "select count(*) from Photos where GalleryId=" + GalleryId + " and Path='" + Path + "'";
			DataTable count = DataAccess.DB.getInstance().ExecuteDataSet(sql).Tables[0];
			if (Convert.ToInt32(count.Rows[0][0]) == 0)
			{
				sql = "insert into Photos (GalleryId, Path, Comment) values (" + GalleryId + ", '" + Path + "', '" + Comment + "')";
				DataAccess.DB.getInstance().ExecuteNonQuery(sql);
			}
		}

		private static void HandleImageFile(ImageFile file, string name, string mappedPath)
		{
			if(file.getContentType().IndexOf(ZIP_FILE)>1)
			{
				UnZip(file.getStream(), name);
			}
			else if (file.getContentType().IndexOf(JPG_FILE)>1)
			{
				HandleJpeg(file, name, mappedPath);
			}
			else 
			{
				throw new SystemException("Not supported file type.");
			}
		}

		private static void HandleJpeg(ImageFile file, string name, string mappedPath)
		{
			System.IO.Stream stream = file.getStream();

			string directoryName = System.IO.Path.GetDirectoryName(mappedPath + "\\");
			if (!Directory.Exists(directoryName))
			{
				Directory.CreateDirectory(directoryName);
			}

			string fileName      = System.IO.Path.GetFileName(file.getFileName());
			System.IO.FileStream streamWriter = File.Create(mappedPath + "\\" + fileName);
				
			int size = 2048;
			byte[] data = new byte[2048];
			while (true) 
			{
				size = stream.Read(data, 0, data.Length);
				if (size > 0) 
				{
					streamWriter.Write(data, 0, size);
				} 
				else 
				{
					break;
				}
			}
			streamWriter.Close();
		}
	}
}
